package co.yixiang.modules.quartz.task;

import cn.hutool.core.util.ObjectUtil;
import co.yixiang.enums.AuctionOrderEnum;
import co.yixiang.logging.aop.log.Log;
import co.yixiang.modules.auction.domain.*;
import co.yixiang.modules.auction.service.*;
import co.yixiang.modules.auction.service.dto.YxAuctionRecordDto;
import co.yixiang.modules.auction.service.mapper.YxAuctionLevelMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionOrderMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionRecordMapper;
import co.yixiang.modules.commom.domain.YxAppdict;
import co.yixiang.modules.commom.service.mapper.YxAppdictMapper;
import co.yixiang.modules.user.domain.*;
import co.yixiang.modules.user.service.YxAuthenticationService;
import co.yixiang.modules.user.service.YxDistributorRelationService;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.mapper.YxDistributorEarningsMapper;
import co.yixiang.modules.user.service.mapper.YxDistributorRelationMapper;
import co.yixiang.modules.user.service.mapper.YxUserinfoMapper;
import co.yixiang.utils.RedisUtils;
import co.yixiang.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.stream.Collectors;

/**
 * @Author ycl
 * @Date2020/8/25 17:22
 * @Version V1.0
 **/
@Slf4j
@Api("定时任务")
@Component("TimedTask")
public class TimedTask {

    @Autowired
    private YxAuctionOrderMapper auctionOrderMapper;

    @Autowired
    private YxUserinfoMapper userinfoMapper;

    @Autowired
    private YxAuthenticationService authenticationService;

    @Autowired
    private YxAuctionRecordService yxAuctionRecordService;

    @Autowired
    private RedisUtils redisUtil;

    @Autowired
    private YxAppdictMapper yxAppdictMapper;

    @Autowired
    private YxAuctionOrderMapper yxAuctionOrderMapper;

    @Autowired
    private YxAuctionRecordMapper yxAuctionRecordMapper;

    @Autowired
    private YxUserService userService;

    @Autowired
    private YxAuctionLevelMapper auctionLevelMapper;

    @Autowired
    private YxDistributorRelationMapper yxDistributorRelationMapper;

    @Autowired
    private YxDistributorEarningsMapper yxDistributorEarningsMapper;

    @Autowired
    private YxAuctionConfigService auctionConfigService;


//    @ApiOperation("定时修改大于7天拍卖订单的状态 || 每天12点执行")
//    @Scheduled(cron = "0 00 12 ? * *")
//    public void updateActionOrderStatus(){
//        List<String> aOIds = auctionOrderMapper.getNotOperatingOrderList(AuctionOrderEnum.RECEIVE_TYPE_0.getValue() , AuctionOrderEnum.STATUS_2.getValue());
//        if(aOIds.size()>0){
//            //修改至待收货
//            auctionOrderMapper.updateActionOrderStatus(AuctionOrderEnum.STATUS_3.getValue() , String.join(",", aOIds));
//        }
//    }

    @ApiOperation("定时月底清除消费额度 | 消费等级  || 每月底23：59执行")
//    @Scheduled(cron = "0 0 0 1 * ?")
    public void clearUserLevel(){
        //清除等级
        userinfoMapper.clearUserLevel();
    }


    @ApiOperation("定时修改当日未拍出的商品")
    @Scheduled(cron = "0 58 23 ? * *")
    public void updateActionReTime(){
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        List<YxAuctionRecord> auctionRecords = yxAuctionRecordService.selectNoBuy();
        auctionRecords.forEach(yxAuctionRecord -> {
            Calendar calendar= Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH , 1);
            yxAuctionRecord.setStartTime(sf.format(calendar.getTime()));
            yxAuctionRecordService.updateById(yxAuctionRecord);
        });
    }

//    @ApiOperation("扫描30分钟未支付的订单")
//    @Scheduled(cron = "0 0/10 * * * ?")
//    public void noPayAuctionOrder(){
//        //获取所有逾期付款订单id key
//        List<String> keys = redisUtil.getLike("auctionOrder");
//        YxAppdict pmfksj=yxAppdictMapper.findAppdictByCode("pmfksj");
//        Integer paimaiTime=60;
//        if(null !=pmfksj){
//            paimaiTime=Integer.parseInt(pmfksj.getMemo());
//        }
//        for (String key:keys) {
//            String orderId =  redisUtil.get(key).toString();
//            YxAuctionOrder yxAuctionOrder=yxAuctionOrderMapper.selectById(orderId);
//            if(null !=yxAuctionOrder){
//                Calendar instance = Calendar.getInstance();
//                instance.setTime(yxAuctionOrder.getCreateTime());
//                instance.add(Calendar.MINUTE,paimaiTime);
//                Date newCreateTime = instance.getTime();
//                //若为待付款
//                if(0==yxAuctionOrder.getStatus()  && newCreateTime.compareTo(new Date())==-1){
//                    //设为已取消
//                    yxAuctionOrder.setStatus(5);
//                    yxAuctionOrder.setIsDel(1);
//                    YxAuctionRecord yxAuctionRecord=yxAuctionRecordMapper.selectById(yxAuctionOrder.getAuctionRecordId());
//                    if(null !=yxAuctionRecord){
//                        yxAuctionRecord.setIsBuy(0);
//                        redisUtil.set("paimai"+yxAuctionRecord.getId(),yxAuctionRecord.getId());
//                    }
//                    yxAuctionOrderMapper.updateById(yxAuctionOrder);
//                    yxAuctionRecordMapper.updateById(yxAuctionRecord);
//                    redisUtil.del(key);
//                }
//            }
//        }
//    }

//    @ApiOperation("计算当天的用户等级||每天23：20计算")
//    @Scheduled(cron = "0 40 22 * * ?")
//    public void calculateUserLevel(){
//        //获取用户列表 -- 根据用户等级除官方号1
//        List<YxUser> userList = userService.list(new QueryWrapper<YxUser>().lambda()
//                .ne(YxUser::getUid , 1)
//                .orderByAsc(YxUser::getNowLevel));
//        //等级 - 除等级0
//        List<YxAuctionLevel> auctionLevels = auctionLevelMapper.selectList(new QueryWrapper<YxAuctionLevel>().lambda()
//                .orderByAsc(YxAuctionLevel::getLevel)
//                .ne(YxAuctionLevel::getLevel , 0));
//        //循环用户列表 修改用户等级
//        for (YxUser user: userList) {
//            Integer level = 0;
//            //循环等级表
//            for (YxAuctionLevel auctionLevel : auctionLevels){
//                //直推数量
//                Integer directDriveNum = auctionLevelMapper.getDirectDriveNumByUId(user.getUid());
//                if(directDriveNum < auctionLevel.getDirectDriveNum()) break;
//                //团队数量
//                Integer teamNum = 0;
//                if(ObjectUtil.isNotEmpty(getUidList(user.getUid()))){
//                    teamNum = auctionLevelMapper.getValidNum(StringUtils.join(getUidList(user.getUid()), ","));
//                }
//                if(teamNum < auctionLevel.getTeamNum()) break;
//                //下级数量
//                if(auctionLevel.getLevel() != 1){
//                    //                    if(ObjectUtil.isNotEmpty(getUidList(user.getUid()))){
////                        lowerLevelNum = auctionLevelMapper.getLowerLevelNum(StringUtils.join(getUidList(user.getUid()), ",") , auctionLevel.getLevel()-1);
////                    }
//                    Integer lowerLevelNum = auctionLevelMapper.getLowerLevelNum1(user.getUid() , auctionLevel.getLevel()-1);
//                    if(lowerLevelNum < auctionLevel.getLowerLevelNum()) break;
//                }
//                level = auctionLevel.getLevel();
//            }
//
//            //修改用户等级
//            user.setNowLevel(level);
//            //修改用户最高等级
//            if(level > user.getHighestLevel()) user.setHighestLevel(level);
//            userService.updateById(user);
//        }
//    }


    @ApiOperation("计算当天的用户佣金||每天23：40计算")
    @Scheduled(cron = "0 40 23 * * ?")
    public void calculatePrice(){
        //一级分佣比例
        YxAppdict storeBrokerageRatioStr = yxAppdictMapper.findAppdictByCode("yjyj");
        //二级分佣比例
        YxAppdict storeBrokerageTwoStr = yxAppdictMapper.findAppdictByCode("ejyj");
        //查询转拍订单
        List<YxAuctionOrder> auctionOrders = yxAuctionOrderMapper.selectAuctionOrderList(AuctionOrderEnum.TYPE_4.getValue());
        for (YxAuctionOrder auctionOrder : auctionOrders) {

            //--------------------------------------------团队分佣-----------------------------------------------------------
            /*YxUser user = userService.getById(auctionOrder.getUserId());
            List<YxUser> ableUser = getAbleUser(user.getNowLevel(), user.getUid());
            if (ObjectUtil.isNotEmpty(ableUser)){
                BigDecimal s = BigDecimal.ZERO;
                for (YxUser user1 : ableUser){
                    Long uid = Long.valueOf(String.valueOf(user1.getUid()));
                    //判断当天用户是否抢拍
                    if(!uid.equals(Long.valueOf("1"))){
                        Integer count = yxAuctionOrderMapper.selectTodayCountByUid(uid);
                        if(count <= 0) continue;
                    }
                    //获取团队佣金比例
                    YxAuctionLevel auctionLevel = auctionLevelMapper.selectById(user1.getNowLevel());
                    BigDecimal ratio = auctionLevel.getTeamEarnings().subtract(s);
                    //团队收益
                    BigDecimal price = auctionOrder.getServiceMoney().multiply(ratio.divide(new BigDecimal(100)));
                    distributorEarnings(auctionOrder.getUserId() , uid , price, 3 , 3 , auctionOrder.getId());
                    s = auctionLevel.getTeamEarnings();
                }
            }*/

            //------------------------------------------上下级分佣-----------------------------------------------------------
            //获取一级分佣用户信息
            YxDistributorRelation firstYxDistributorRelation=yxDistributorRelationMapper.getByUid(auctionOrder.getUserId());
            if(null !=firstYxDistributorRelation){
                //判断当天用户是否抢拍
                /*Integer count = yxAuctionOrderMapper.selectTodayCountByUid(firstYxDistributorRelation.getPUid());
                if (count > 0 || firstYxDistributorRelation.getPUid().equals(Long.valueOf("1"))){*/
                    BigDecimal price1 ;
                    if(null !=storeBrokerageRatioStr){
                        price1 = auctionOrder.getServiceMoney().multiply(new BigDecimal(storeBrokerageRatioStr.getMemo()).divide(new BigDecimal(100)));
                    }else{
                        price1 = auctionOrder.getServiceMoney().multiply(new BigDecimal(20).divide(new BigDecimal(100)));
                    }

                    distributorEarnings(auctionOrder.getUserId() , firstYxDistributorRelation.getPUid() , price1, 1 , 1 , auctionOrder.getId());
               /* }*/
                //获取二级分佣用户信息
                YxDistributorRelation secondYxDistributorRelation=yxDistributorRelationMapper.getByUid(firstYxDistributorRelation.getPUid());
                if(null !=secondYxDistributorRelation){
                    //判断当天用户是否抢拍
                    /*Integer count1 = yxAuctionOrderMapper.selectTodayCountByUid(secondYxDistributorRelation.getPUid());
                    if(count1 > 0 || secondYxDistributorRelation.getPUid().equals(Long.valueOf("1"))){*/
                        BigDecimal price2 ;
                        if(null !=storeBrokerageTwoStr){
                            price2 = auctionOrder.getServiceMoney().multiply(new BigDecimal(storeBrokerageTwoStr.getMemo()).divide(new BigDecimal(100)));
                        }else{
                            price2 = auctionOrder.getServiceMoney().multiply(new BigDecimal(10).divide(new BigDecimal(100)));
                        }
                        distributorEarnings(auctionOrder.getUserId() , secondYxDistributorRelation.getPUid() , price2 , 2 , 1 , auctionOrder.getId());
                    }
                /*}*/
            }
        }
    }

    @ApiOperation("获取团队用户id")
    public List<Long> getUidList(Long uid){
        List<Long> us = new ArrayList<>();
        //获取下级
        List<Long> uidByPid = auctionLevelMapper.getUidByPid(uid);
        if(ObjectUtil.isNotEmpty(uidByPid)){
            //下级
            us.addAll(uidByPid);
            //查看是否还存在下级
            List<Long> uidList = getUidList(uidByPid);
            if(ObjectUtil.isNotEmpty(uidList)) us.addAll(uidList);
        }
        return us;
    }

    @ApiOperation("获取团队用户id")
    public List<Long> getUidList(List<Long> uList){
        List<Long> us = new ArrayList<>();
        //获取下级
        List<Long> uidByPid = auctionLevelMapper.getUidByPids(StringUtils.join(uList,","));
        if(ObjectUtil.isNotEmpty(uidByPid)){
            //下级
            us.addAll(uidByPid);
            List<Long> uidList = getUidList(uidByPid);
            if(ObjectUtil.isNotEmpty(uidList)) us.addAll(uidList);
        }
        return us;
    }

    /**
     * 给予上级收益
     *
     * @param uid1 用户id
     * @param uid2 上级用户id
     * @param price 佣金
     * @param cate 1-直接 2-间接 3-团队
     * @param type 1-拍卖商品 2-购买商品 3-团队收益
     * @param oid 订单id
     */
    public void distributorEarnings(Long uid1 , Long uid2 , BigDecimal price , Integer cate , Integer type , Long oid ){
        if(price.compareTo(BigDecimal.ZERO) == 1) {
            YxDistributorEarnings yxDistributorEarnings=new YxDistributorEarnings();
            yxDistributorEarnings.setIsOver(1);
            yxDistributorEarnings.setType(type);
            yxDistributorEarnings.setStatus(1);
            yxDistributorEarnings.setPrice(price);
            yxDistributorEarnings.setUid(uid2);
            yxDistributorEarnings.setDUid(uid1);
            yxDistributorEarnings.setOid(oid);
            yxDistributorEarnings.setCate(cate);
            yxDistributorEarningsMapper.insert(yxDistributorEarnings);
            YxUser firstUser=userService.getById(uid2);
            if(null !=firstUser){
                firstUser.setBrokeragePrice(firstUser.getBrokeragePrice().add(yxDistributorEarnings.getPrice()));
                userService.updateById(firstUser);
            }
        }
    }

    /**
     * 查找用户上级等级
     *
     * @param uid 用户id
     *
     */
    public List<Map<String , Object>> searchUserLevel(Long uid){
        List<Map<String , Object>> list = new ArrayList<>();
        //获取当前用户等级
        YxUser user = userService.getById(uid);
        YxDistributorRelation one = yxDistributorRelationMapper.getByUid(uid);
        if(ObjectUtil.isNotEmpty(one)){
            //上级用户
            YxUser user1 = userService.getById(one.getPUid());
            if(user.getNowLevel() < user1.getNowLevel()) {
                Map<String , Object> map = new HashMap<>();
                map.put("uid" , user1.getUid());
                map.put("level" , user1.getNowLevel());
                list.add(map);
                List<Map<String, Object>> list1 = searchUserLevel(user1.getUid());
                list.addAll(list1);
            }
        }
        return list;
    }



    /**
     * 获取所以上级
     * @param uid 用户id
     *
     */
    public List<YxUser> getUpUserByUid(Long uid){
        List<YxUser> list = new ArrayList<>();
        //获取当前用户等级
        YxUser user = userService.getById(uid);
        list.add(user);
        YxDistributorRelation one = yxDistributorRelationMapper.getByUid(uid);
        if(ObjectUtil.isNotEmpty(one)){
            //上级用户
            List<YxUser> list1 = getUpUserByUid(one.getPUid());
            list.addAll(list1);
        }
        return list;
    }

    /**
     * 获取可获取收益的上级
     * @param level
     * @param uid
     * @return
     */
    public List<YxUser> getAbleUser(Integer level , Long uid){
        List<YxUser> upUserByUid = getUpUserByUid(uid);
        List<YxUser> a1 = new ArrayList<>();
        //过滤同等级
        for (YxUser user :  upUserByUid) {
            if(level < user.getNowLevel()){
                a1.add(user);
                level = user.getNowLevel();
            }
        }
        System.out.println("可获取收益的上级——————>" +a1.stream().map(p -> p.getUid()).collect(Collectors.toList()));
        return a1;
    }




    /**************数据加载**************/
    @ApiOperation("拍卖商品基本信息存储 每天早上1点进行拍卖之前存储")
    @Scheduled(cron = "0 0 01 * * ?")
    public void auctionProductInfo(){
        System.out.println("拍卖商品基本信息存储...");
        //查询场次
        List<AuctionProductD> list = yxAuctionRecordMapper.getListProduct();
        redisUtil.deleteByPrex("product");
        list.forEach(auctionProduct -> {
            redisUtil.set("product" + auctionProduct.getId(), JSONObject.fromObject(auctionProduct).toString());
        });
    }


    @ApiOperation("拍卖商品列表存储 每天早上1：20点进行拍卖之前存储")
    @Scheduled(cron = "0 20 01 * * ?")
    public void auctionProduct(){
        //查询场次
        List<YxAuctionConfig> list = auctionConfigService.list(new QueryWrapper<YxAuctionConfig>().lambda()
                .eq(YxAuctionConfig::getIsDel, 0));
        redisUtil.deleteByPrex("time");
        list.forEach(yxAuctionConfig -> {
            //查看当前专场是否存在商品
            storageProduct(yxAuctionConfig.getId());
        });
    }


    @ApiOperation("拍卖商品存储 每一秒查询进行拍卖商品")
    @Scheduled(fixedRate = 1000)
    @Async
    public void auctionProductM(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        System.out.println("商品列表刷新中...");
        //查询场次
        List<YxAuctionConfig> list = auctionConfigService.list(new QueryWrapper<YxAuctionConfig>().lambda()
                .eq(YxAuctionConfig::getIsDel, 0));
        list.forEach(yxAuctionConfig -> {
            //开始时间
            Date sDate= null;
            Calendar calendar = Calendar.getInstance();

            try {
                sDate = simpleDateFormat.parse(yxAuctionConfig.getStartTime());
                calendar.setTime(sDate);
                calendar.add(Calendar.HOUR, -1);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Date eDate= null;
            try {
                eDate = simpleDateFormat.parse(yxAuctionConfig.getEndTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            //当前时间
            Date parse = null;
            try {
                String dateString = simpleDateFormat.format(new Date());
                parse = simpleDateFormat.parse(dateString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if(calendar.getTime().getTime() <= parse.getTime() && eDate.getTime() > parse.getTime()){
                //期间中 刷新内容
                storageProduct(yxAuctionConfig.getId());
            }
        });

    }

    public void storageProduct(Long timeId){
        Integer auctionProductCount = yxAuctionRecordMapper.getYxAuctionProductCount(timeId);
        if(auctionProductCount == 0){
            //塞入空对象
            Page page = new Page(1,30);
            Page<YxAuctionRecordDto> yxAuctionProductList = yxAuctionRecordMapper.getYxAuctionProductList(page, timeId);
            redisUtil.set("time"+timeId+"&page"+1 , JSONObject.fromObject(yxAuctionProductList).toString());
        }else {
            Integer a = (auctionProductCount/30) +1;
            if (auctionProductCount%30 != 0 && auctionProductCount>30 ) a += 1;
            for (int i = 1 ; i <= a ; i++){
                Page page = new Page(i,30);
                Page<YxAuctionRecordDto> yxAuctionProductList = yxAuctionRecordMapper.getYxAuctionProductList(page, timeId);
                for (YxAuctionRecordDto yxAuctionRecordDto:yxAuctionProductList.getRecords()) {
                    Object o = redisUtil.get("product" + yxAuctionRecordDto.getAuctionProductId());
                    JSONObject jsonObject=JSONObject.fromObject(o);
                    YxAuctionProduct auctionProduct = (YxAuctionProduct)JSONObject.toBean(jsonObject, YxAuctionProduct.class);
                    yxAuctionRecordDto.setYxAuctionProductDto(auctionProduct);
                }
                redisUtil.set("time"+timeId+"&page"+i , JSONObject.fromObject(yxAuctionProductList).toString());
            }
        }
    }


}
